const LinkedListNode = require('./linkedListNode');
module.exports = class LinkedList {
  constructor() {
    this.head = null;
    this.tail = null;
  }
  // 添加节点到链表头部
  prepend(value) {
    const node = new LinkedListNode(value, this.head);
    this.head = node;
    if (!this.tail) {
      this.tail = node;
    }
    return this;
  }
  // 添加节点到链表尾部
  append(value) {
    const node = new LinkedListNode(value);

    if (!this.head) {
      this.head = node;
      this.tail = node;

      return this;
    }

    this.tail.next = node;
    this.tail = node;
  }
  // 删除链表节点
  delete(value) {
    if (!this.head) {
      return null;
    }

    let deleteNode = null;
    // 由于是单链表，头部没有引用，需要额外处理
    while (this.head && this.head.value === value) {
      deleteNode = this.head;
      this.head = this.head.next;
    }

    let currentNode = this.head;

    while (currentNode.next) {
      if (value === currentNode.next.value) {
        deleteNode = currentNode;
        currentNode = currentNode.next.next;
      } else {
        currentNode = currentNode.next;
      }
    }

    if (this.tail.value === value) {
      this.tail = currentNode;
    }

    return deleteNode;
  }
  // 查找链表节点
  find(value) {
    if (!this.head) {
      return null;
    }
    let currentNode = this.head;

    while (currentNode) {
      if (value && currentNode.value === value) {
        return currentNode;
      }
      return currentNode.next;
    }
    return null;
  }
  // 删除链表尾
  deleteTail() {
    const deletedTail = this.tail;

    if (this.head === this.tail) {
      this.head = null;
      this.tail = null;

      return deletedTail;
    }

    let currentNode = this.head;

    while (currentNode) {
      if (!currentNode.next.next) {
        currentNode.next = null;
      } else {
        currentNode = currentNode.next;
      }
    }
    this.tail = currentNode;
    return deletedTail;
  }
  // 删除链表头
  deleteHead() {
    if (!this.head) {
      return null;
    }

    const deletedHead = this.head;

    if (this.head.next) {
      this.head = this.head.next;
    } else {
      this.head = null;
      this.tail = null;
    }
    return deletedHead;
  }
  fromArray(values) {
    values.forEach(this.append);
    return this;
  }
  toArray() {
    const nodes = [];
    let currentNode = this.head;

    while (currentNode) {
      nodes.push(currentNode);
      currentNode = currentNode.next;
    }

    return nodes;
  }
  toString(callback) {
    return this.toArray()
      .map((node) => node.toString(callback))
      .toString();
  }
  /**
   * 反转链表
   */
  reverse() {
    let currentNode = this.head;
    // 相当于两个同步指针，next指针始终在prev指针后面
    let prevNode = null;
    let nextNode = null;

    while (currentNode) {
      nextNode = currentNode.next;

      currentNode.next = prevNode;

      prevNode = currentNode;
      currentNode = nextNode;
    }

    this.tail = this.head;
    this.head = prevNode;

    return this;
  }
};
